use std::{sync::Mutex, time::Duration};
use local_ip_address::local_ip;
use std::net::IpAddr;
use axum::{
    middleware::{from_fn, Next},
    response::Response,
    routing::get,
    Router,
};
use axum_tonic::{GrpcStatus, NestTonic, RestGrpcService};
use tonic::{Status,Request};
pub mod hello_world {
    tonic::include_proto!("helloworld"); // 这里指定的字符串必须与proto的包名称一致
}
use hello_world::greeter_server::{Greeter, GreeterServer};
use hello_world::{HelloReply, HelloRequest};


#[derive(Debug, Default)]
pub struct MyGreeter {}

#[tonic::async_trait]
impl Greeter for MyGreeter {
    async fn say_hello(
        &self,
        request: Request<HelloRequest>, // 接收以HelloRequest为类型的请求
    ) -> Result<tonic::Response<HelloReply>, Status> { // 返回以HelloReply为类型的示例作为响应
        println!("Got a request: {:?}", request);

        let reply = hello_world::HelloReply {
            message: format!("{:?}:Hello {}!",local_ip().unwrap(), request.into_inner().name).into(), // 由于gRPC请求和响应中的字段都是私有的，所以需要使用 .into_inner()
        };

        Ok(tonic::Response::new(reply)) // 发回格式化的问候语
    }
}


#[tokio::main]
async fn main() {

        let grpc_router = Router::new()
            .nest_tonic(GreeterServer::new(MyGreeter{}));
        let rest_router = Router::new().route("/health", get(health));
        // Combine both services into one
        let service = RestGrpcService::new(rest_router,grpc_router);

        axum::Server::bind(&"0.0.0.0:8080".parse().unwrap())
            .serve(service.into_make_service())
            .await
            .unwrap();
    

}

async fn health() -> String {
    "ok".to_owned()
}